package br.com.velp.sudecap.mb.auditoria;

import br.com.velp.sudecap.comum.BaseController;
import br.com.velp.sudecap.comum.SpringConstants;
import br.com.velp.sudecap.enumerator.TipoOperacaoEnum;
import br.com.velp.sudecap.service.LogAuditoriaService;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.lindbergframework.spring.scope.AccessScoped;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Controller;

/**
 * <sumario> 
 * <objetivo> "Rastreabilidade" </objetivo> 
 * <autor> EDUARDO SANTOS DE OLIVEIRA </autor> 
 * <versao>1.0.0.0</versao> 
 * <data_criacao> 30.07.2013 </data_criacao> 
 * <data_ultima_alteracao> 26.11.2013 </data_ultima_alteracao>
 * <requisitos_afetados> N/A </requisitos_afetados> 
 * <descricao> Controller Responsável Pela Exibição
 *             do Histórico de Modificações de Registros
 *             No Sistema.
 * </descricao>
 * </sumario>
 */
@Controller("historicoAuditoriaController")
@Lazy(SpringConstants.LAZY_BEANS)
@AccessScoped
public class HistoricoAuditoriaController extends BaseController {
    
    public static final Long serialVersionUID = 1l;
    
    //Constantes
    private static final String ID = "id";
    private static final String SENHA = "senha";
    private static final String USUARIO = "usuario";
    private static final String OPERACAO = "operacao";
    private static final String DATA_HORA = "dataHora";
    private static final String ESTILO_FUNDO_AMARELO = "fundo_amarelo";
    private static final String PACOTE_ENTIDADE = "br.com.velp.sudecap.entidade.";

    //Atributos Utilizados Pela Funcionalidade
    private List<String> nomesColunas;
    private List<Map<String, Object>> mapasHistorico;
    
    @Autowired
    private LogAuditoriaService logAuditoriaService;

    /**
     * Recupera o Histórico de Mofificações da Entidade (Inserção e Atualizações)
     * @param Long idEntidade
     * 
     */
    public void carregarHistorico(Long idEntidade, String nomeClasse) {

        try {
            
            this.mapasHistorico = this.logAuditoriaService.recuperarMapaHistoricoModificacoes(
                    idEntidade,
                    Class.forName(PACOTE_ENTIDADE.concat(nomeClasse)),
                    TipoOperacaoEnum.INSERT,
                    TipoOperacaoEnum.UPDATE);

            carregarNomesColunas();
            
        } catch (Exception ex) {
            
            tratarExcessao(ex);
            
        }

    }

    /**
     * 
     * Responsável Por Carregar Os Nomes das Colunas 
     * (Chaves dos Mapas) 
     * 
     */
    private void carregarNomesColunas() {

        this.nomesColunas = new ArrayList<String>();
        
        //Caso o Mapa de Histórico de Modificações Esteja Vazio,
        //Deve-se Desconsiderar o Carregamento dos Mapas
        if (this.mapasHistorico.isEmpty()) {
            return;
        }

        //Recupera o Primeiro Elemento Através do Mapa de Histórico
        //de Registros de LOG
        Map<String, Object> historico = this.mapasHistorico.get(0);
        
        //Carregar os Nomes das Colunas Para Montagem 
        //Dinâmica do DataTable
        for (String chave : historico.keySet()) {
            if(!getColunasCallback().contains(chave)){
                this.nomesColunas.add(chave);
            }
        }

    }

    /**
     * 
     * Aplica o Estilo 'Fundo Amarelo' Caso o Valor da Coluna Tenha
     * Sido Modificado, Ao Ser Comparado Com o Valor da Linha Anterior
     * 
     * @param String coluna
     * @param int rowIndex
     * 
     * @return String estiloCampoAlterado
     * 
     */
    public String aplicarEstiloCampoAlterado(String coluna, int rowIndex) {
        
        //Situação Que Indica o Último Índice a Ser Verificado
        if (rowIndex < 0 || this.mapasHistorico.size() <= 1 || rowIndex == (this.mapasHistorico.size() - 1)) {
            return "";
        }

        Object valorAtual = this.mapasHistorico.get(rowIndex).get(coluna);
        Object proximoValor = this.mapasHistorico.get(rowIndex + 1).get(coluna);

        if (!isIguais(proximoValor, valorAtual)) {
            return ESTILO_FUNDO_AMARELO;
        }

        return null;

    }
    
    /**
     * 
     * Lista de Colunas Que Devem Ser Desconsideradas
     * Na Geração Do Painel Dialog de Apresentação dos
     * Registros de LOG do Sistema.
     * 
     * @return List<String> colunasBlackList
     * 
     */
    private List<String> getColunasCallback() {
        
        List<String> auditoria = new ArrayList<String>();
        
        auditoria.add(SENHA);
        auditoria.add(ID);
        auditoria.add(USUARIO);
        auditoria.add(OPERACAO);
        auditoria.add(DATA_HORA);
        
        return auditoria;
        
    }

    // <editor-fold desc="GETTERS AND SETTERS" defaultstate="collapsed">    
    public List<Map<String, Object>> getMapasHistorico() {
        return mapasHistorico;
    }

    public void setMapasHistorico(List<Map<String, Object>> mapasHistorico) {
        this.mapasHistorico = mapasHistorico;
    }

    public List<String> getNomesColunas() {
        return nomesColunas;
    }

    public void setNomesColunas(List<String> nomesColunas) {
        this.nomesColunas = nomesColunas;
    }
    // </editor-fold>
    
}
